﻿using System;
using System.Collections.Generic;
using Baseballdata.Context;
using Baseballdata.Data;
using System.Data.Linq;
using System.Linq;
using System.Text;
namespace Pitchers
{
    class Pitchers
    {
        private double getStd(List<double> dbList)
        {
            double avg = dbList.Average();
            double sumOfDev = 0;
            foreach (double value in dbList)
            {
                sumOfDev += (value) * (value);
            }
            double soda = sumOfDev / dbList.Count;
            return Math.Sqrt(soda - (avg * avg));
        }
        private double getMean(List<double> dbLst)
        {
            double mean = 0;
            foreach (double average in dbLst)
            {
                mean += average;
            }
            mean /= dbLst.Count;
            return mean;
        }

        private double getZScore(double stats, double mean, double std)
        {

            double zScore = 0;
            zScore = ((stats - mean) / std);

            return zScore;
        }
        static void Main(string[] args)
        {
            Pitchers newPrg = new Pitchers();
            List<double> hofDbls = new List<double>();
            List<double> hofTrips = new List<double>();
            List<double> hofHits = new List<double>();
            List<double> hofABS = new List<double>();
            List<double> hofHRS = new List<double>();
            List<double> hofRuns = new List<double>();
            List<double> hofRBIS = new List<double>();
            List<double> hofSBS = new List<double>();
            //List<double> hofAVG = new List<double>();
            //List<double> nwDls = new List<double>();
            double zValueDoubles = 0;
            double zValueTrips = 0;
            double zValueHits = 0;
            double zValueABS = 0;
            double zValueHRS = 0;
            double zValueRuns = 0;
            double zValueRBIS = 0;
            double zValueSBS = 0;
            
            Dictionary<string, double> zscore = new Dictionary<string, double>();
            
            BaseballdataDataContext db = new BaseballdataDataContext();
            
            //Start
            DateTime startTime = DateTime.Now;
            var rslt = from hof in db.HallOfFames
                       where hof.inducted.Equals('Y') && hof.category == "Player"
                       //&& hof.hofID == hofPlayerid
                       select hof;

            Console.WriteLine("HOF Pitchers---------");
            var count = 0;
            foreach (var q in rslt)
            {
                var fld = (from f in db.Fieldings
                           join m in db.Masters on f.playerID equals m.playerID
                           where (f.POS.Equals('P') && q.hofID == m.hofID)
                           orderby f.playerID ascending
                           group f by f.playerID into field
                           select new
                           {
                               Id = field.Key
                           }).Distinct();
                foreach (var n in fld)
                {
                    var master = from b in db.Pitchings
                                 join m in db.Masters on b.playerID equals m.playerID
                                 where (n.Id == b.playerID)
                                 && b.ERA != null
                                 group b by b.playerID into pitching
                                 select new
                                 {
                                     Id = pitching.Key,
                                     W = pitching.Average(i2 => i2.W),
                                     L = pitching.Average(i3 => i3.L),
                                     H = pitching.Average(i8 => i8.H),
                                     ER = pitching.Average(i4 => i4.ER),
                                     HR = pitching.Average(i5 => i5.HR),
                                     BB = pitching.Average(i6 => i6.BB),
                                     SO = pitching.Average(i7 => i7.SO),
                                     ERA = pitching.Average(i9 => i9.ERA)
                                 };
                    foreach (var s in master)
                    {
                        hofDbls.Add((double)s.W);
                        hofTrips.Add((double)s.L);
                        hofHits.Add((double)s.H);
                        hofABS.Add((double)s.ER);
                        hofHRS.Add((double)s.HR);
                        hofRuns.Add((double)s.BB);
                        hofRBIS.Add((double)s.SO);
                        hofSBS.Add((double)s.ERA);
                        count++;
                    }
                }
            }

            //Console.WriteLine("{0},{1},{2},{3},{4}", totalDoubles, totalTriples, totalHits, totalHomeRuns, count);
            double hofDblsStd = newPrg.getStd(hofDbls);
            double hofDblsMean = newPrg.getMean(hofDbls);

            double hofTripsStd = newPrg.getStd(hofTrips);
            double hofTripsMean = newPrg.getMean(hofTrips);

            double hofHitsStd = newPrg.getStd(hofHits);
            double hofHitsMean = newPrg.getMean(hofHits);

            double hofABSStd = newPrg.getStd(hofABS);
            double hofABSMean = newPrg.getMean(hofABS);

            double hofHRSStd = newPrg.getStd(hofHRS);
            double hofHRSMean = newPrg.getMean(hofHRS);

            double hofRunsStd = newPrg.getStd(hofRuns);
            double hofRunsMean = newPrg.getMean(hofRuns);

            double hofRBISStd = newPrg.getStd(hofRBIS);
            double hofRBISMean = newPrg.getMean(hofRBIS);

            double hofSBSStd = newPrg.getStd(hofSBS);
            double hofSBSMean = newPrg.getMean(hofSBS);

            //double hofAVGStd = newPrg.getStd(hofAVG);
            //double hofAVGMean = newPrg.getMean(hofAVG);
            //End
            DateTime endTime = DateTime.Now;
            Console.WriteLine("{0} {1}", hofDblsStd, hofDblsMean);
            Console.WriteLine("Total records {0}", count);
            Console.WriteLine("end printing--------");
            //Start time
            DateTime start = DateTime.Now;
            var plyList = from bttr in db.Pitchings
                          where (from fldgs in db.Fieldings
                                 where fldgs.POS.Equals('P')
                                 group fldgs by fldgs.playerID into fld
                                 where fld.Count() > 4
                                 select fld.Key).Contains(bttr.playerID)
                                  &&
                                  !(from mst in db.Masters
                                    join hoff in db.HallOfFames on mst.hofID equals hoff.hofID
                                    select mst.hofID).Contains(bttr.playerID)
                          orderby bttr.playerID
                          group bttr by bttr.playerID into batter
                          select new
                          {
                              ID = batter.Key
                          };


            Console.WriteLine("start for new ID");
            double ctagain = 0;
            foreach (var qq in plyList)
            {
                var mastrB = from b in db.Pitchings
                             join m in db.Masters on b.playerID equals m.playerID
                             where (qq.ID == b.playerID)
                             && b.ERA != null
                             group b by b.playerID into pitching
                             select new
                             {
                                 Id = pitching.Key,
                                 W = pitching.Average(i2 => i2.W),
                                 L = pitching.Average(i3 => i3.L),
                                 H = pitching.Average(i8 => i8.H),
                                 ER = pitching.Average(i4 => i4.ER),
                                 HR = pitching.Average(i5 => i5.HR),
                                 BB = pitching.Average(i6 => i6.BB),
                                 SO = pitching.Average(i7 => i7.SO),
                                 ERA = pitching.Average(i9 => i9.ERA)
                             };
                foreach (var sq in mastrB)
                {
                    zValueDoubles = newPrg.getZScore((Double)sq.W, hofDblsMean, hofDblsStd);
                    zValueTrips = newPrg.getZScore((Double)sq.L, hofTripsMean, hofTripsStd);
                    zValueHits = newPrg.getZScore((Double)sq.H, hofHitsMean, hofHitsStd);
                    zValueABS = newPrg.getZScore((Double)sq.ER, hofABSMean, hofABSStd);
                    zValueHRS = newPrg.getZScore((Double)sq.HR, hofHRSMean, hofHRSStd);
                    zValueRuns = newPrg.getZScore((Double)sq.BB, hofRunsMean, hofRunsStd);
                    zValueRBIS = newPrg.getZScore((Double)sq.SO, hofRBISMean, hofRBISStd);
                    zValueSBS = newPrg.getZScore((Double)sq.ERA, hofSBSMean, hofSBSStd);
                    double totals = ((zValueDoubles + zValueTrips + zValueHits + zValueABS + zValueHRS + zValueRuns + zValueRBIS + zValueSBS) / 8);
                    zscore.Add(sq.Id, totals);
                    ctagain++;

                }
            }
            //endtime
            DateTime end = DateTime.Now;
            TimeSpan duration1 = endTime - startTime;
            TimeSpan duration2 = end - start;
            Console.WriteLine("Time to calculate std and mean for hall of fame players {0}, {1}", duration1.TotalMinutes, duration1.TotalSeconds);
            Console.WriteLine("Time to calculate zscore for all pitchers {0}, {1}", duration2.TotalMinutes, duration2.TotalSeconds);
            Console.WriteLine("ct for new Id {0}", ctagain);



            Console.ReadLine();

            //results.ToList();
        }
    }
}
